1. Field of the Invention
Embodiments of the present invention relate to the field of class loading in a Java Virtual Machine environment. More particularly, embodiments of the present invention relate generally to automated code-source indexing in the Java Virtual Machine environment.
2. Related Art
Java programs are composed of named classes (e.g., “java.lang.String”) and other data is referred to as resource data (e.g., “resource”. Classes and resources are loaded into a Java Virtual Machine (JVM) by a class loader. Each class loader contains one or more code-sources (e.g., class or resources archives, such as “.jar” or “.zip” files) from which to obtain class files that are converted into class instances or resource data for application use. Class and resource names are prefixed by a “package” name, such as “java.lang” for the “String” class. Generally, many classes share a package name.
The term “class loading” refers to the process of locating the bytes for a given class name and converting them into a Java class instance. All “java.lang.Class” instances within a JVM start life as an array of bytes structured in the class format defined by the JVM specification.
Class loading is performed by the JVM during the startup process, and subsequently by subclasses of the “java.lang.ClassLoader” class. These “classloaders” provide an abstraction that allows the JVM to load classes without any knowledge of where the class bytes come from. This enables both local and remote storage as well as dynamic class generation. Furthermore, class loaders provide “dynamic-loading” capabilities that provide a great deal of extensibility to the Java language and are the basis for the mobile code capabilities of the Java language. In addition to loading classes, classloaders can be used to load native code (e.g., .dll files).
A classloader is a subclass of the “java.lang.ClassLoader” class that is responsible for loading classes. In a JVM environment class loaders are arranged in a tree hierarchy, where each class loader has a single parent. Each class loader is designed to work with one or more code-sources. For example, each classloader contains one or more code-sources that are class or resource archives (e.g., jars, zip files, etc.) from which to obtain class files to convert into class instances or resource data for application use.
A code-source is a root location from which the classloader searches for classes. Although the name implies the loading of classes only, class loaders can be used to load any file from the configured code-sources using, for example, the “getResource” and “getResourceAsStream” methods. Code-sources can be defined to represent physical storage of binary class files, java sources that must first be compiled, or even classes generated on the fly. For example, a code-source can be a directory, a zip file, a jar file, etc. A classloader uses each code-source, along with a class package name, to define a location to search for classes.
When a class load event occurs, a class loader is selected (e.g., the “initiating” classloader) to search for the class. In a standard search algorithm, the classloader searches up the parent chain in the classloader tree of the JVM environment before searching for the class in the initiating classloader. Each loader visited during the search must consult its list of code-sources to try to find the class. The classloader that locates and converts the class file into a class instance is referred to as the “defining” loader. The first matching class is returned. Once loaded, the class is added to a cache that is used to short-circuit the search process, thus avoiding code-source consultation.
In complex JVM environment that contain multiple class loaders, it is common for an initiating class loader to have many ancestors. Each of the ancestor, class loaders may contain many code-sources. As a result, in a typical class loading event, a significant amount of time is devoted to locating the specific code-source in a class loader, for example. That is, each of the code-sources associated with a specific class loader would be queried non-discriminately, in order, to determine whether it is able to access that class. As a result, the search mechanism would waste time consulting ancestor class loaders that cannot load the class, and waste time consulting code-sources that cannot satisfy the search. As a result, unnecessary time and resources are wasted in conducting a search for a class loading event.